<?php

/*
 * Ref Link https://github.com/phpredis/phpredis
 * */

class PhpRedis
{
    protected $hostInfo = array();
    protected $redisHandle = 0;

    public function __construct($hostInfo = array()){
        $this->connect($hostInfo);
    }
    public function connect($hostInfo = array(),$pconnect = 0){
        $this->redisHandle = new Redis();
        if(!isset($hostInfo['host'])){
            return;
        }
        if($pconnect){
            $return = $this->redisHandle->pconnect($hostInfo['host'],$hostInfo['port'],$hostInfo['timeout'],$hostInfo['persistent_id'],$hostInfo['retry_interval'],$hostInfo['read_timeout']);
            if($return == FALSE){
                echo "Error";
            }
            return;
        }
        /**
        主机：字符串。可以是主机，也可以是unix域套接字的路径。从版本5.0.0开
        始，可以指定架构端口：int，可选
        超时：浮点值，以秒为单位（可选，默认值为0，表示无限制）
        保留：如果指定重试间隔，则应为空
        重试间隔：int，以毫秒为单位的值（可选）
        读取超时：浮点值，以秒为单位（可选，默认值为0，表示无限制）
         */
        $return = $this->redisHandle->connect($hostInfo['host'],$hostInfo['port'],$hostInfo['timeout'],$hostInfo['reserved'],$hostInfo['retry_interval'],$hostInfo['read_timeout']);
        if($return == FALSE){
            echo "Error";
        }
    }
    private function auth($auth){
        $return = $this->redisHandle->auth($auth);
        if($return == FALSE){
            echo "Error";
        }
    }

    public function getStatusInfo($opt = ''){
        $return = array();
        if($opt){
            $return = $this->redisHandle->info($opt);
        }
        $return = $this->redisHandle->info();
        return $return;
    }
    //选择数据库DBnumber
    protected function selectDBNumber( $dbindex = 0){
        return $this->redisHandle->select($dbindex);
    }
    //以原子方式交换一个redis数据库
    protected function swapdbData($dbindex1,$dbindex2){
        return $this->redisHandle->swapdb($dbindex1,$dbindex2);
    }
    //设置redis客户端选项
    /**
     * Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE
     * Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP
     * Redis::OPT_SERIALIZER, Redis::SERIALIZER_IGBINARY
     * Redis::OPT_SERIALIZER, Redis::SERIALIZER_MSGPACK
     * Redis::OPT_PREFIX, 'myAppName:'
     *
     */
    protected function setOption($parameterName,$parameterValue){
        return $this->redisHandle->setOption($parameterName,$parameterValue);
    }
    //
    protected function getOption($parameterName){
        return $this->redisHandle->getOption($parameterName);
    }
    //Redis Server相关函数
    //开始后台重写aof（仅追加文件）
    protected function bgRewriteAOF(){
        return $this->redisHandle->bgRewriteAOF();
    }
    //异步将数据集保存到磁盘（在后台）
    protected function bgSave(){
        return $this->redisHandle->bgSave();
    }
    //获取或设置Redis服务器配置参数。
    /**
     * $redis->config("GET", "*max-*-entries*");
    $redis->config("SET", "dir", "/var/run/redis/dumps/");
    */
    protected function config($getOrSet,$value){
        return $this->redisHandle->config($getOrSet,$value);
    }
    //返回所选数据库中的键数。
    protected function getDbKeysCount(){
        return $this->redisHandle->dbSize();
    }
    //从所有数据库中删除所有密钥。
    protected function delAllDatabases(){
        return $this->redisHandle->flushAll();
    }
    //从当前数据库中删除所有密钥。
    protected function delDbData(){
        return $this->redisHandle->flushDb();
    }
    //返回最后一个磁盘保存的时间戳。
    protected function lastSaveDate(){
        return $this->redisHandle->lastSave();
    }
    /**
     * 重置info方法返回的统计信息。
    以下是重置的计数器：
    击键空间
    键空间未命中
    处理的命令数
    接收的连接数
    过期密钥数
    */
    protected function resetStatInfoCounters(){
        return $this->redisHandle->resetStat();
    }
    //同步将数据集保存到磁盘（等待完成）
    protected function save(){
        return $this->redisHandle->save();
    }
    /**
     * 描述：更改主从属状态
     * 参数 要么是主机（字符串），要么是端口（int），要么是没有参数来停止从属。
    */
    protected function slaveOf($host = '',$port = 0){
        if($port){
            $this->redisHandle->slaveOf($host,$port);
        }
        $this->redisHandle->slaveOf();
    }
    //返回redis服务器时间
    protected function serverTime(){
        return $this->redisHandle->time();
    }
    //redis慢日志
    protected function slowLog($cmd = '',$len = 10){
        $return = 0;
        if($cmd == 'get'){
            $return = $this->redisHandle->slowLog($cmd, $len);
        }
        $return = $this->redisHandle->slowLog($cmd);
        return $return;
    }
    //追加一个值到key里面
    protected function append($key,$value){
        $size = $this->redisHandle->append($key,$value);
        return $size;
    }
    //获取与指定键相关的值
    protected function getDataByKey($key){
        return $this->redisHandle->get($key);
    }
    //设置指定键的值
    protected function setDataByKey($key,$value,$ttl = 0){
        return $this->redisHandle->set($key,$value,$ttl);
    }
    //设置指定键的值TTL时间毫秒级单位
    protected function pSetEx($key,$ttl,$value){
        return $this->redisHandle->pSetEx($key,$ttl,$value);
    }
    //删除键
    protected function unlink($keys,$unlink = 0){
        //del unlink
        if($unlink){
            /* If using Redis >= 4.0.0 you can call unlink */
            return $this->redisHandle->unlink($keys);
        }
        return $size = $this->redisHandle->del($keys);

    }
    //检测key是否存在
    protected function existsByKey($keys){
        return $this->redisHandle->exists($keys);
    }
    //将存储在键上的数字增加一个。如果第二个参数被填充，它将被用作增量的整数值。
    protected function incrOrincrBy($key,$interval = 0){
        if($interval){
            return $this->redisHandle->incr($key);
        }
        return $this->redisHandle->incrBy($key,$interval);
    }
    //允许负数
    protected function incrByFloat($key,$float){
        return $this->redisHandle->incrByFloat($key,$float);
    }
    //将存储在键上的数字减1。如果第二个参数被填充，它将被用作减量的整数值。
    protected function decrOrDecrBy($key,$interval=0){
        if($interval){
            return $this->redisHandle->decrBy($key,$interval);
        }
        return $this->redisHandle->decr($key);
    }
    //获取所有指定键的值。如果一个或多个密钥不存在，则该数组将在密钥的位置包含false。
    protected function mGet($keyArr){
        return $this->redisHandle->mGet($keyArr);
    }
    //设置值并返回该键处的原来的值。
    protected function getSet($key,$value){
        return $this->redisHandle->getSet($key,$value);
    }
    //将获取一个redis随机的键
    protected function getRandomKey(){
        return $this->redisHandle->randomKey();
    }
    //将密钥移动到其他数据库。
    protected function moveKeyForDatabase($key,$dbIndex){
        return $this->redisHandle->move($key,$dbIndex);
    }
    //重命名key
    protected function renameKey($srckey,$dstkey){
        return $this->redisHandle->rename($srckey,$dstkey);
    }
    //设定key的失效时间ttl
    protected function expireKey($key,$ttl){
        return $this->redisHandle->expire($key,$ttl);
    }
    //设置项目的到期日期（时间戳）。pexpireat需要以毫秒为单位的时间戳。
    protected function expireAtTime($key,$time){
        return $this->redisHandle->expireAt($key, $time);
    }
    //获取redis keys
    protected function getKeys($keyword = '*'){
        return $this->redisHandle->keys($keyword);
    }
    //扫描键返回数组
    /* With Redis::SCAN_RETRY enabled */
    //$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
    //$arr_keys = $redis->scan(NULL)
    /**
    $redis->object("encoding", "l"); // → ziplist 编码类型
    $redis->object("refcount", "l"); // → 1 引用计数
    $redis->object("idletime", "l"); // → 400 (以秒为单位,精确到10秒).
     */
    /**
    返回给定键指向的数据类型。根据键指向的数据类型，此方法将返回以下值：
     * string: Redis::REDIS_STRING
    set: Redis::REDIS_SET
    list: Redis::REDIS_LIST
    zset: Redis::REDIS_ZSET
    hash: Redis::REDIS_HASH
    other: Redis::REDIS_NOT_FOUND
     */
    /**
    描述：返回较大字符串的子字符串

    注意：redis中也支持substr，但不推荐使用它。
     */
    protected function getSubstrByKey($key,$start,$end){
        return $this->redisHandle->getRange($key,$start,$end);
    }
    /**
    描述：更改较大字符串的子字符串。

    参数

    键偏移值

    返回值

    字符串：修改后字符串的长度。
     */
    protected function setStrRangeByKey($key,$offset,$str){
        return $this->redisHandle->setRange($key,$offset,$str);
    }
    /**
     * 获取字符串值的长度。
    */
    protected function getStrLen($key){
        return $this->redisHandle->strLen($key);
    }
    /**
     * $redis->del('s');
    $redis->sAdd('s', 5);
     * var_dump($redis->sort('s')); // 1,2,3,4,5
    var_dump($redis->sort('s', ['sort' => 'desc'])); // 5,4,3,2,1
    var_dump($redis->sort('s', ['sort' => 'desc', 'store' => 'out'])); // (int)5
    */
    //以秒（TTL）或毫秒（PTTL）为单位返回给定密钥的剩余生存时间。
    protected function getTTLBykey($key,$pttl = 0){
        if($pttl){
            return $this->redisHandle->pttl($key);
        }
        return $this->redisHandle->ttl($key);
    }
    //迁移redis实例到另一个redis实例
    /**
     * 主机字符串。目标主机
    端口整数。要连接到的TCP端口。
    键字符串或数组。
    目标数据库整数。目标数据库。
    超时整数。此转移的最大时间量。
    复制布尔值，可选。我们应该把复制标志发送给redis吗？
    替换布尔值，可选。我们应该把替换标志发送给redis吗
     * /* Migrate multiple keys (requires Redis >= 3.0.6)
    $redis->migrate('backup', 6379, ['key1', 'key2', 'key3'], 0, 3600);
    */
    protected function srcMigrateDst($host,$port,$key,$destinationdb,$timeout,$copy,$replace){
        return $this->redisHandle->migrate($host,$port,$key,$destinationdb,$timeout,$copy,$replace);
    }
    //Redis hash 是一个 string 类型的 field 和 value 的映射表，hash 特别适合用于存储对象。
    protected function hSetNx($key,$hashkey,$value,$replace = 1){
        if ($replace){
            return $this->redisHandle->hSet($key,$hashkey,$value);
        }
        return $this->redisHandle->hSetNx($key,$hashkey,$value);
    }
    //
    protected function hGet($key,$hashkey){
        return $this->redisHandle->hGet($key,$hashkey);
    }
    //返回哈希值的长度（以项数为单位）
    protected function hLen($key){
        return $this->redisHandle->hLen($key);
    }
    //
    protected function hKeysVals($key,$vals = 0){
        if($vals == 1){
            return $this->redisHandle->hVals($key);
        }elseif ($vals == 2) {
            return $this->redisHandle->hKeys($key);
        }
        return $this->redisHandle->hGetAll($key);
    }
    //
    protected function hExists($key,$hashkey){
        return $this->redisHandle->hExists($key,$hashkey);
    }
    /**
     * $redis->del('h');
    $redis->hIncrBy('h', 'x', 2);  returns 2: h[x] = 2 now.
$redis->hIncrBy('h', 'x', 1);  h[x] ← 2 + 1. Returns 3
    */
    protected function hIncrBy($key,$hashkey,$value,$float = 1){
        if ($float == 1){
            return $this->redisHandle->hIncrByFloat($key,$hashkey,$value);
        }
        return $this->redisHandle->hIncrBy($key,$hashkey,$value);
    }
    /**
     * $redis->hMGet('h', ['field1', 'field2']);
     * $redis->hMSet('user:1', ['name' => 'Joe', 'salary' => 2000]);
    */
    protected function hMGetMSet($key,$hashkey,$set = 1){
        if ($set == 1){
            return $this->redisHandle->hMSet($key,$hashkey);
        }
        return $this->redisHandle->hMGet($key,$hashkey);
    }
    /**
     * $it = NULL;
    在我们完成迭代之前不要返回空数组
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
while($arr_keys = $redis->hScan('hash', $it)) {
foreach($arr_keys as $str_field => $str_value) {
echo "$str_field => $str_value\n"; 打印哈希成员和值
}
}
    */
    //Lists列表数据类型
    //弹出列表的数据和键值 blpop若键值不存在则阻塞 brpop不阻塞
    protected function blOrbrPop($keyArr,$timeout,$emptyLock = 0){
        if ($emptyLock == 1){
            /* process 1
            $redis->del('key1');
            $redis->blPop('key1', 10);
            阻塞等待 10 seconds

            process 2
            $redis->lPush('key1', 'A');

            process 1
            ['key1', 'A'] is returned
            */
            return $this->redisHandle->blpop($keyArr,$timeout);
        }
        return $this->redisHandle->brpop($keyArr,$timeout);
    }
    //bRPopLPush 阻塞
    //返回存储在指定键处的列表的指定元素。
    /*
    $redis->rPush('key1', 'A');
    $redis->rPush('key1', 'B');
    $redis->rPush('key1', 'C');  key1 => [ 'A', 'B', 'C' ]
    $redis->lIndex('key1', 0);  'A'
    $redis->lIndex('key1', -1);  'C'
    $redis->lIndex('key1', 10);  `FALSE`
    */
    protected function lIndex($key,$index){
        return $this->redisHandle->lIndex($key,$index);
    }
    /*在列表的节点偏移之前或之后插入值
    返回值 列表中元素的数目，如果数据透视不存在，则为-1。
    $redis->del('key1');
    $redis->lInsert('key1', Redis::AFTER, 'A', 'X');  0 -1
    $redis->lPush('key1', 'A');
    $redis->lPush('key1', 'B');
    $redis->lPush('key1', 'C');

    $redis->lInsert('key1', Redis::BEFORE, 'C', 'X');  4
    $redis->lRange('key1', 0, -1);  ['A', 'B', 'X', 'C']

    $redis->lInsert('key1', Redis::AFTER, 'C', 'Y');  5
    $redis->lRange('key1', 0, -1);  ['A', 'B', 'X', 'C', 'Y']

    $redis->lInsert('key1', Redis::AFTER, 'W', 'value');  -1
    */
    protected function lInsert($key,$before = 1,$pivot,$value){
        //三元运算符
        return $this->redisHandle->lInsert($key,$before == 1 ? Redis::BEFORE :Redis::AFTER,$pivot,$value);

    }
    /*
     * 返回并删除列表的第一个元素。
     * 如果命令成功执行则返回字符串，若列表为空则为FALSE
     * $redis->rPush('key1', 'A');
    $redis->rPush('key1', 'B');
    $redis->rPush('key1', 'C');  key1 => [ 'A', 'B', 'C' ]
    $redis->lPop('key1');  key1 => [ 'B', 'C' ]
     * */
    protected function lPop($key){
        return $this->redisHandle->lPop($key);
    }
    /*将字符串值添加到列表的头部（左侧）。如果密钥不存在，则创建列表。如果密钥存在且不是列表，则返回false。
    如果成功，则返回新的列表长度，如果失败，请将其设置为False。
    $redis->del('key1');
    $redis->lPush('key1', 'C'); // returns 1
    $redis->lPush('key1', 'B'); // returns 2
    $redis->lPush('key1', 'A'); // returns 3
    key1 now points to the following list: [ 'A', 'B', 'C' ]
     * */
    protected function lPush($key,$value){
        return $this->redisHandle->lPush($key,$value);
    }
    /*如果列表存在，则将字符串值添加到列表的头部（左侧）。并不会创建列表
     * */
    protected function lPushx($key,$value){
        return $this->redisHandle->lPushx($key,$value);
    }
    /*返回存储在范围[索引开始，索引结束]中指定键处的列表的指定元素
     * */
    protected function lRange($key,$start,$end){
        return $this->redisHandle->lRange($key,$start,$end);
    }
    /*从列表中删除value元素的第一次计数。如果count为零，则移除所有匹配元素。如果计数为负，则元素从尾部移到头部。

     * */
    protected function lRemove($key,$value,$valCount){
        return $this->redisHandle->lRem($key,$value,$valCount);
    }
    /*
     * 在索引处用新值设置列表。
     * */
    protected function lSet($key,$index,$value){
        return $this->redisHandle->lSet($key,$index,$value);
    }
    /*
     * 修剪现有列表，以便它只包含指定范围的元素。indexStart indexEnd
     * */
    protected function lTrim($key,$start,$end){
        return $this->redisHandle->lTrim($key,$start,$end);
    }
    /*
     * 返回并删除列表的最后一个元素。
     * */
    protected function rPop($key){
        return $this->redisHandle->rPop($key);
    }
    /*
     * rPopLPush将列表key1 right pop出来 left push key2列表
     * */
    protected function rPopLPush($srcKey,$dstKey){
        return $this->redisHandle->rPopLPush($srcKey,$dstKey);
    }
    /*
     * */
    protected function rPush($key,$value,$newCreate = 1){
        $action = $newCreate == 1 ? 'rPush' : 'rPushX';

        return $this->redisHandle->$action($key,$value);

    }
    protected function lLen($key){
        return $this->redisHandle->lLen($key);
    }
    /*
     * Sets 集合
     * */
    /*
     * 将值添加到存储在键处的设置值。如果此值已在集合中，则返回false。
     * */
    protected function sAdd($key,$value){
        return $this->redisHandle->sAdd($key,$value);
    }
    /*
     * 返回由键标识的集合的基数。
     * */
    protected function sCard($key){
        return $this->redisHandle->sCard($key);
    }
    /*
     * 执行n个集合之间的差异并返回它。
     * ...$args 可变参数列表
     * */
    protected function sDiff(...$args){
        return $this->redisHandle->sDiff($args);
    }
    /*
     * 执行与sdiff相同的操作，但将结果存储在第一个参数键中
     * var_dump($args)
     * array_reverse()	以相反的顺序返回数组。
     * array_pop()	删除数组的最后一个元素（出栈）。
     * */
    protected function sDiffStore($dstKey,...$args){
        return $this->redisHandle->sDiffStore($dstKey,$args);
    }
    /*
     * 返回集合的成员，该集合是由在指定键处保存的所有集合的交集产生的。
     * */
    protected function sInter(...$args){
        return $this->redisHandle->sInter($args);
    }
    protected function sInterStore($dstkey,...$args){
        return $this->redisHandle->sInterStore($dstkey,$args);
    }
    /*
     *检查值是否是存储在密钥处的集合的成员。
     * */
    protected function sIsMember($key,$value){
        return $this->redisHandle->sIsMember($key,$value);
    }
    /*
     * 返回集合的内容。
     * */
    protected function sMembers($key){
        return $this->redisHandle->sMembers($key);
    }
    //sMove
    /* 将指定成员从set at srckey移到set at dstkey

     * */
    protected function sMove($srcKey,$dstKey,$memberValue){
        return $this->redisHandle->sMove($srcKey,$dstKey,$memberValue);
    }
    /*
     *从键的设置值中移除并返回随机元素。
     * 从键处的设置值返回随机元素，而删除它。
     * */
    protected function sPop($key,$count = 1){
        return $this->redisHandle->sPop($key,$count);
    }
    /*
     * 从键处的设置值返回一个随机元素，而不删除它。
     * */
    protected function sRandMember($key,$count = 1){
        return $this->redisHandle->sRandMember($key,$count);
    }
    /*
     * 从存储在密钥处的设置值中删除指定的成员。
     * */
    protected function sRem($key,...$members){
        return $this->redisHandle->sRem($key,$members);
    }
    /*
     * 执行n个集合之间的并集并返回它。
     * */
    protected function sUnion($keyArr){
        return $this->redisHandle->sUnion($keyArr);
    }
    /*
     * 执行与sunion相同的操作，但将结果存储在第一个键中
     * return 结果集的基数，如果缺少键则为false。intval
     * */
    protected function sUnionStore($key,$keyArr){
        return $this->redisHandle->sUnionStore($key,$keyArr);
    }
    /*
     * sScan
     * 描述：扫描集合中的成员
       参数
       key：要搜索的集合
       迭代器：对迭代器的长引用
       模式：字符串，要匹配的可选模式
       计数：有多少成员每次返回（ReDIS可能会返回不同的数量）
       返回值
       array，boolean:phpredis将返回一个键数组，或者在完成迭代后返回false
     * Redis::OPT_SCAN, Redis::SCAN_RETRY 在完成之前不要返回空结果 推荐
     * Redis::OPT_SCAN, Redis::SCAN_NORETRY 每次迭代后返回，即使为空
     * */
    protected function sScan($optScan =1,$key,&$it,$pattern = '*pattern*',&$count){
        $optScan = $optScan == 1?Redis::SCAN_RETRY:Redis::SCAN_NORETRY;
        $this->redisHandle->setOption(Redis::OPT_SCAN,$optScan);
        return $this->redisHandle->sScan($key,$it,$pattern ,$count);
    }
    // Sorted sets 有序集合
    /*
     * return 数组：一个带有关键成员的数组和最高或最低元素的分数或空数组，如果没有元素弹出，则到达超时。
     * */
    protected function bzPopMinMax($minMax = 1,$sKeyArr,$timeout){
        if ($minMax == 1){
            return $this->redisHandle->bzPopMin($sKeyArr,$timeout);
        }
        return $this->redisHandle->bzPopMax($sKeyArr,$timeout);
    }
    /*
     * 将一个或多个成员添加到排序集，或更新其分数（如果已存在）
     * return 如果添加了元素，则为1。意外为0。
     * */
    protected function zAdd($key ,$score,$value){
        return $this->redisHandle->zAdd($key,$score,$value);
    }
    /*
     * 返回有序集的基数。zCard, zSize
     * */
    protected function zSize($key){
        return $this->redisHandle->zSize($key);
    }
    /*
     * 返回存储在指定键上的已排序集的元素数，这些元素的分数在[开始，结束]范围内。
     * 在开始或结束之前添加括号会将其从范围中排除。+inf和-inf也是有效的限制。
     * */
    protected function zCount($key,$scoreStart,$scoreEnd){
        return $this->redisHandle->zCount($key,$scoreStart,$scoreEnd);
    }
    /*
     * 将已排序集合中成员的分数按给定的量递增。
     * */
    protected function zIncrBy($key,$double,$memberVal){
        return $this->redisHandle->zIncrBy($key,$double,$memberVal);
    }
    /*
     * 创建第二个参数中给定的排序集的交集。联合的结果将存储在第一个参数定义的排序集中。
     * aggregateFunction聚合函数"SUM", "MIN", or "MAX"count,avg,count_big
     * */
    protected function zinterstore($outKey,$zSetsKeyArr,$weightRangeArr,$groupBy = ''){
        if(empty($groupBy) && empty($weightRangeArr)){
            return $this->redisHandle->zinterstore($outKey,$zSetsKeyArr);
        }elseif (empty($groupBy) && !empty($weightRangeArr)){
            return $this->redisHandle->zinterstore($outKey,$zSetsKeyArr,$weightRangeArr);
        }elseif (!empty($groupBy) && empty($weightRangeArr)){
            return $this->redisHandle->zinterstore($outKey,$zSetsKeyArr,FALSE,$groupBy);
        }
        return $this->redisHandle->zinterstore($outKey,$zSetsKeyArr,$weightRangeArr,$groupBy );
    }
    /*
     * 返回存储在指定键上的有序集的元素范围，其值在范围[开始，结束]内。
     * */
    protected function zRange($key,$start,$end,$withscores = false){
        return $this->redisHandle->zRange($key,$start,$end,$withscores);
    }
    /*
     * 返回存储在指定键上的已排序集的元素，这些元素的分数在[开始，结束]范围内。
     * 在开始或结束之前添加括号会将其从范围中排除。+inf和-inf也是有效的限制。
     * zRevRangeByScore以相反的顺序返回相同的项目，当开始和结束参数交换时。
     * $redis->zRangeByScore('key', 0, 3, ['withscores' => TRUE, 'limit' => [1, 1]]);
     * */
    protected function zRangeByScore($key,$scoreStart,$scoreEnd,$optArr,$rev = false){
        if ($rev == true){
            return $this->redisHandle->zRevRangeByScore($key,$scoreStart,$scoreEnd,$optArr);
        }
        return $this->redisHandle->zRangeByScore($key,$scoreStart,$scoreEnd,$optArr);
    }
    /*
     * 返回一个排序集合中成员的词典范围，假设成员具有相同的分数。
     * 最小值和最大值必须以“（”（独占）、“[”（包含）开头，或者正好是值“-”（负inf）或“+”（正inf）。
     * 必须使用三个或五个参数调用该命令，否则将返回false。
     * foreach(['a','b','c','d','e','f','g'] as $c)
            $redis->zAdd('key',0,$c);

        $redis->zRangeByLex('key','-','[c') /* ['a','b','c'];
        $redis->zRangeByLex('key','-','(c') /* ['a','b']
        $redis->zRangeByLex('key','-','[c',1,2) /* ['b','c']
     * */
    protected function zRangeByLex($key,$min,$max,$offset,$limit){
        if($limit){
            return $this->redisHandle->zRangeByLex($key,$min,$max,$offset,$limit);
        }
        return $this->redisHandle->zRangeByLex($key,$min,$max);
    }
    //zRank, zRevRank
    /*
     * 返回指定排序集中给定成员的等级，
       得分最小的项目从0开始。
       Zrevrank是得分最高的项目从0开始。
    返回值

    长整型，这个条目的排序等级位置。
     * */
    protected function zRevRank($key,$member,$rev = 1){
        $fun = $rev == 1?'zRevRank':'zRank';
        return $this->redisHandle->$fun($key,$member);
    }
    /*
     * 从排序集中删除一个或多个成员。
     * return long：删除的成员数。
     * Note: zDelete and zRemove are an alias for zRem
     * */
    protected function zRem($key,...$args){
        return $this->redisHandle->zRem($key,$args);
    }
    /*
     * 删除存储在指定键上的排序集元素，这些元素的权重在范围内[start,end]
     * 返回值 long从排序集中删除的值的数目
     * Note: zDeleteRangeByRank is an alias for zRemRangeByRank
     * */
    protected function zRemRangeByRank($key,$start,$end){
        return $this->redisHandle->zRemRangeByRank($key,$start,$end);
    }
    /*
     * 删除存储在指定键处的排序集元素，这些元素的分数在范围内 [start,end].
     * Parameters
        key
        start: double or "+inf" or "-inf" string
        end: double or "+inf" or "-inf" string
     * 返回值 long从排序集中删除的值的数目
     * Note: zDeleteRangeByScore and zRemoveRangeByScore are an alias for zRemRangeByScore
     * */
    protected function zRemRangeByScore($key,$start,$end){
        return $this->redisHandle->zRemRangeByScore($key,$start,$end);
    }
    /*
     * 按相反顺序返回存储在范围[开始，结束]中指定键处的已排序集的元素。开始和停止被解释为基于零的索引：
     * 0 the first element, 1 the second ...
        -1 the last element, -2 the penultimate ...
     * Parameters
        key
        start: long
        end: long
        withscores: bool = false
     * return 包含指定范围内的值的数组。
     * */
    protected function zRevRange($key,$start,$end,$withScoresBool = false){

        return $this->redisHandle->zRevRange($key,$start,$end,$withScoresBool);

    }
    /*
     * 返回指定排序集中给定成员的分数。
     * */
    protected function zScore($key,$member){
        return $this->redisHandle->zScore($key,$member);
    }
    /*
     * 创建第二个参数中给定的排序集的并集。联合的结果将存储在第一个参数定义的排序集中。
     * 第三个可选参数定义要应用于输入中已排序集的权重。arrayZSetKeys与arrayWeights一一对应关系
     * 在这种情况下，在应用聚合之前，权重将乘以排序集中每个元素的得分。
     * 第四个参数定义了aggregate选项，该选项指定如何聚合联合的结果。
     * Parameters
        keyOutput
        arrayZSetKeys
        arrayWeights
        aggregateFunction 聚合函数Either "SUM", "MIN", or "MAX"定义在zunionstore期间对重复项使用的行为
     * return 新排序集中的个数。
     * Note: zUnion is an alias for zunionstore
     * */
    protected function zunionstore($outputKey,$arrayZSetKey,$arrayWeight,$aggregateFunction = ''){
        if (empty($aggregateFunction) &&!empty($arrayWeight)){
            return $this->redisHandle->zunionstore($outputKey,$arrayZSetKey,$arrayWeight);
        }elseif (empty($aggregateFunction) && empty($arrayWeight)){
            return $this->redisHandle->zunionstore($outputKey,$arrayZSetKey);
        }elseif (!empty($aggregateFunction) &&empty($arrayWeight)){
            return $this->redisHandle->zunionstore($outputKey,$arrayZSetKey,null,$aggregateFunction);
        }
        return $this->redisHandle->zunionstore($outputKey,$arrayZSetKey,$arrayWeight,$aggregateFunction);
    }
    /*
     * 用可选的模式和计数扫描已排序的成员集
     * 数组，boolean phpredis将从redis返回匹配键，或者在迭代完成时返回false
     * $redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
     * */
    protected function zScan($it = null){
        return $arr_matches = $this->redisHandle->zScan('zset', $it, '*pattern*');
    }
    //Geocoding 地理编码
    /*
     * 将一个或多个地理空间项添加到指定键。必须使用至少一个经度、纬度、成员三元组调用此函数。
     * return 整数：添加到地理空间键的元素数。
     * geoAdd($key, $longitude, $latitude, $member,$longitude2, $latitude2, $member2,)
     * */
    protected function geoAdd($key, ...$args){
        return $this->redisHandle->geoAdd($key, $args);
    }
    /*
     * 检索地理空间索引的一个或多个元素的地理哈希字符串。
     * return array 一个或多个redis geohash编码字符串。
     * geoHash($key, $member [, $member, $member, ...]);
     * */
    protected function geoHash($key, ...$members){
        return $this->redisHandle->geoHash($key, $members);
    }
    /*
     * 返回每个请求成员的经度和纬度位置。
     * return 数组：一个或多个经纬度位置
     * geoPos($key, $member [, $member, $member, ...]);
     * */
    protected function geoPos($key, ...$members){
        return $this->redisHandle->geoPos($key, $members);
    }
    /*
     * 返回地理空间集中两个成员之间的距离。如果传递了单位，则必须是以下值之一：
     * 'm' => Meters 'km' => Kilometers 'mi' => Miles 'ft' => Feet
     * return double：以请求的单位（默认为米）表示的两个通过的成员之间的距离。
     * geoDist($key, $member1, $member2 [, $unit]);
     * */
    protected function geoDist($key, $member1, $member2 , $unit = ''){
        if (empty($unit)){
            return $this->redisHandle->geoDist($key, $member1, $member2 );
        }
        // $unit = null try it?
        return $this->redisHandle->geoDist($key, $member1, $member2 , $unit);
    }
    /*
     * 返回地理空间信息在调用方指定半径内的集成员。
     * 选项数组
        可以使用控制redis返回结果方式的各种选项调用georadius命令。下表描述了phpredis支持的选项。所有选项都不区分大小写。
    Key	Value	Description
    COUNT	integer > 0	限制返回的结果数
            WITHCOORD	返回匹配成员的经纬度
            WITHDIST	返回与中心的距离
            WITHHASH	返回原始geohash编码的分数
            ASC	        按升序对结果排序
            DESC	    按降序对结果排序
    STORE	key         将结果存储在密钥中
    STOREDIST	key	    将结果存储为键中的距离
    注意：同时传递asc和desc选项是没有意义的，但是如果都传递了，则使用最后传递的选项。
    注意：在redis集群中使用store[dist]时，store key必须与query key在同一个槽中，否则会出现crosslot错误。
    return 混合：当没有传递存储选项时，此函数返回一个结果数组。如果传递给此函数，则返回存储条目数。
    geoRadius($key, $longitude经度, $latitude维度, $radius半径, $unit单位 [, Array $options]);
    $options = ['WITHDIST']; 数组
     * */
    protected function geoRadius($key, $longitude, $latitude, $radius, $unit , $options=array()){
        return $this->redisHandle->geoRadius($key, $longitude, $latitude, $radius, $unit , $options);
    }
    /*
     * 此方法与GeaDeaS完全相同，只是代替经度和纬度作为“源”，而通过地理空间集合中的现有成员。
     * return 数组：给定指定的距离和半径，与成员足够接近的零个或多个条目。
     * geoRadiusByMember($key, $member集合中成员, $radius半径, $units单位 [, Array $options]);
     * */
    protected function geoRadiusByMember($key, $member, $radius, $units , $options = array()){
        return $this->redisHandle->geoRadiusByMember($key, $member, $radius, $units , $options);
    }
    //Streams信息流消息流
    /*
     * 代表消费者组确认一条或多条消息。
     * return redis报告为已确认的消息数。
     * $obj_redis->xAck($stream, $group, $arr_messages);
     * */
    protected function xAck($stream, $group, $arr_messages){
        return $this->redisHandle->xAck($stream, $group, $arr_messages);
    }
    /*
     * 向流中添加消息
     * return String: The added message ID
     * $obj_redis->xAdd($str_key, $str_id, $arr_message[, $i_maxlen, $boo_approximate]);
     * $i_maxlen = 1000,将最大流长度设置为1000
     * $boo_approximate 布尔值，近似值
     * example $obj_redis->xAdd('mystream', "*", ['field' => 'value'], 1000, true);
     * */
    protected function xAdd($str_key, $str_id, $arr_message, $i_maxlen = 0, $boo_approximate = 0){
        if (empty($i_maxlen)){
            return $this->redisHandle->xAdd($str_key, $str_id, $arr_message);
        }
        return $this->redisHandle->xAdd($str_key, $str_id, $arr_message, $i_maxlen, $boo_approximate);
    }
    /*
     * 声明一个或多个挂起消息的所有权。
     * Options Array
        $options = [
            注意：“time”和“idle”是互斥的
            'IDLE' => $value,  将空闲时间设置为$value ms  ,
            'TIME' => $value,  将空闲时间设置为now-$value
            'RETRYCOUNT' => $value,  将消息retrycount更新为$value
            'FORCE',  即使消息没有挂起，也可以申请
            'JUSTID',  指示redis只返回id
        ];
     * return 数组：一个消息id数组和相应的数据，或者只是一个id数组（如果传递了“justid”选项）。
     * xClaim($str_key, $str_group, $str_consumer, $min_idle_time最小空闲时间, $arr_ids, [$arr_options]);
     * */
    protected function xClaim($str_key, $str_group, $str_consumer, $min_idle_time = 0, $arr_ids, $arr_options =array()){

        return $this->redisHandle->xClaim($str_key, $str_group, $str_consumer, $min_idle_time , $arr_ids,$arr_options);

    }
    /*
     * 从流中删除一条或多条消息。
     * return 删除的消息数
     * $obj_redis->xDel($str_key, $arr_ids);
     * */
    protected function xDel($str_key, $arr_ids){
        return $this->redisHandle->xDel($str_key, $arr_ids);
    }
    /*
     * 此命令用于创建、销毁或管理用户组。
     * return 此命令根据执行的特定xgroup命令返回不同的类型。
     * $obj_redis->xGroup('HELP');
        $obj_redis->xGroup('CREATE', $str_key, $str_group, $str_msg_id
    , [$boo_mkstream]); $boo_mkstream = true 如果不存在，则创建流
        $obj_redis->xGroup('SETID', $str_key, $str_group, $str_msg_id);
        $obj_redis->xGroup('DESTROY', $str_key, $str_group);
        $obj_redis->xGroup('DELCONSUMER', $str_key, $str_group, $str_consumer_name);
     * */
    protected function xGroup($instruction,$str_key,$str_group,$str_msg_id = 0,$boo_mkstream = 0){
        //字符串转换成大写
        $instruction = strtoupper($instruction);
        switch ($instruction){
            case 'CREATE':
                return $this->redisHandle->xGroup('CREATE', $str_key, $str_group, $str_msg_id
                    , $boo_mkstream);
                //break;
            case 'SETID':
                return $this->redisHandle->xGroup('SETID', $str_key, $str_group, $str_msg_id);
                //break;
            case 'DESTROY':
                return $this->redisHandle->xGroup('DESTROY', $str_key, $str_group);
                //break;
            case 'DELCONSUMER':
                //$str_consumer_name = $str_msg_id;
                return $this->redisHandle->xGroup('DELCONSUMER', $str_key, $str_group, $str_msg_id);
                //break;
            default:
                return $this->redisHandle->xGroup('HELP');
        }
    }
    /*
     * 获取有关流或消费者组的信息。
     * return 此命令根据使用的子命令返回不同的类型。
     * $obj_redis->xInfo('CONSUMERS', $str_stream, $str_group);
        $obj_redis->xInfo('GROUPS', $str_stream);
        $obj_redis->xInfo('STREAM', $str_stream);
        $obj_redis->xInfo('HELP');
     * */
    protected function xInfo($instruction,$str_stream,$str_group = ''){
        $instruction = strtoupper($instruction);
        switch ($instruction){
            case 'GROUPS':
            case 'STREAM':
                return $this->redisHandle->xInfo($instruction,$str_stream);
            case 'CONSUMERS':
                return $this->redisHandle->xInfo('CONSUMERS', $str_stream, $str_group);
            default:
                return $this->redisHandle->xInfo('HELP');
        }
    }
    /*
     * 获取给定流的长度
     * return 流中的消息数。
     * */
    protected function xLen($str_stream){
        return $this->redisHandle->xLen($str_stream);
    }
    /*
     * 获取有关给定流中挂起消息的信息。
     * $obj_redis->xPending($str_stream, $str_group [, $str_start, $str_end, $i_count, $str_consumer]);
     * return 有关挂起消息的信息，根据xpending的特定调用以各种形式提供
     * $obj_redis->xPending('mystream', 'mygroup', '-', '+', 1, 'consumer-1');
     * */
    protected function xPending($str_stream, $str_group , $str_start = 0, $str_end = 0, $i_count = 1, $str_consumer = ''){
        if(empty($str_consumer)){
            return $this->redisHandle->xPending($str_stream, $str_group );
        }
        return $this->redisHandle->xPending($str_stream, $str_group , $str_start , $str_end , $i_count, $str_consumer );
    }
    /*
     * 从给定的流中获取一系列消息。
     * $str_start = '-', $str_end = '+'
     * return 流中请求范围内的消息。
     * */
    protected function xRange($str_stream, $str_start, $str_end , $i_count = 0){
        if ($i_count){
            return $this->redisHandle->xRange($str_stream, $str_start, $str_end , $i_count);
        }
        return $this->redisHandle->xRange($str_stream, $str_start, $str_end );
    }
    /*
     * 这与xrange相同，只是结果以相反的顺序返回。还要注意，redis颠倒了“开始”和“结束”的顺序。
     * $obj_redis->xRevRange($str_stream, $str_end, $str_start [, $i_count]);
     * */
    protected function xRevRange($str_stream, $str_start, $str_end , $i_count = 0){
        if ($i_count){
            return $this->redisHandle->xRevRange($str_stream, $str_start, $str_end , $i_count);
        }
        return $this->redisHandle->xRevRange($str_stream, $str_start, $str_end );
    }
    /*
     * 从一个或多个流读取数据，只返回大于命令中发送的ID。
     * $obj_redis->xRead($arr_streams [, $i_count个数, $i_block 阻塞等待);
     * $obj_redis->xRead(['stream1' => '$'], 1, 0);
     * 只接收新消息（$=最后一个ID），并等待一个新消息，不受时间限制
     * return 流中比传递给redis的id更新的消息（如果有）。
     * */
    protected function xRead($arr_streams , $i_count = 0, $i_block = 0){
        if ($i_count){
            return $this->redisHandle->xRead($arr_streams , $i_count, $i_block);
        }
        return $this->redisHandle->xRead($arr_streams );
    }
    /*
     * 将流长度调整到给定的最大值。如果“近似”标志被篡改，ReDIS将使用您的大小作为提示，但只修整树在整个节点（这是更有效的）。
     * $obj_redis->xTrim($str_stream, $i_max_len [, $boo_approximate]);
     * return 从流中修剪的消息数。
     * */
    protected function xTrim($str_stream, $i_max_len , $boo_approximate = false){
        return $this->redisHandle->xTrim($str_stream, $i_max_len , $boo_approximate);
    }
    //Pub/sub
    /*
     * 按模式订阅频道
     * patterns: 要匹配的模式数组
       callback: 包含对象和方法的字符串或数组。回调将得到四个参数 ($redis, $pattern, $channel, $message)
        return 回调中的任何非空返回值都将返回给调用方。
     * */
    /*
     * Example

    function pSubscribe($redis, $pattern, $chan, $msg) {
    echo "Pattern: $pattern\n";
    echo "Channel: $chan\n";
    echo "Payload: $msg\n";
    }
    */
    /*
    function callback_function($redisObj, $pattern, $channel, $message){
        //处理结构体过程
    }
    */
    protected function pSubscribe($pattern,$callback_function){
        return $this->redisHandle->pSubscribe($pattern,$callback_function);
    }
    /*
     * 将消息发布到频道。警告：此功能将来可能会更改。
     * Parameters
        channel: 发布到的频道
        message: string
    $redis->publish($channel = 'chan-1', $message = 'hello, world!'); // send message.
     * */
    protected function publish($channel = 'chan-1', $message = 'hello, world!'){
        return $this->redisHandle->publish($channel, $message );
    }
    /*
     * 订阅频道。警告：此功能将来可能会更改。
     * Parameters
        channels: 要订阅的频道数组
        callback: 字符串或数组($instance, 'method_name'). 回调函数接收3个参数：redis实例、频道名和消息。
        返回值：混合。回调中的任何非空返回值都将返回给调用方。
     * */
    /* 回调处理函数
    function callback_function($redisObj,$channel,$message){
        switch ($channel){
            case 'channel-1':
                break;
            case 'channel-2':
                break;
            default:
        }
    }
    */
    protected function subscribe($channelArr,$callback_function ){
        return $this->redisHandle->subscribe($channelArr,$callback_function );
    }
    /*
     * 允许您获取有关redis发布/订阅系统的信息的命令。
     * Parameters keyword: String, which can be: "channels", "numsub", or "numpat"
     * argument:可选，变型。对于“channels”子命令，可以传递字符串模式。对于“numsub”，是一个频道名数组。
     * Return value: CHANNELS: 返回一个数组，其中成员是匹配的频道。
     * NUMSUB: 返回键/值数组，其中键是频道名称，值是它们的计数。
     * NUMPAT: 包含活动模式订阅数的整数返回
     * ("channels"); All channels
     * ("channels", "*pattern*");  Just channels matching your pattern
     * ("numsub", ["chan1", "chan2"]); Get subscriber counts for 'chan1' and 'chan2'
     * ("numpat");  Get the number of pattern subscribers
     * */
    protected function pubSub($keyword,$args = false){
        return $this->redisHandle->pubSub($keyword,$args);
    }
    //Generic
    /*
     *对redis服务器执行任意命令的方法
     * 参数: 此方法是可变的，接受各种类型（string、long、double）的动态参数数，但必须至少传递一个参数（command关键字本身）。
     * return 根据服务器本身返回的内容，返回值可以是多种类型。不会对返回值进行后期处理，必须由客户端代码处理。
     *
     * */
    //for example
    /*
     *  Returns: true
        $redis->rawCommand("set", "foo", "bar");

        Returns: "bar"
        $redis->rawCommand("get", "foo");

        Returns: 3
        $redis->rawCommand("rpush", "mylist", "one", 2, 3.5));

        Returns: ["one", "2", "3.5000000000000000"]
        $redis->rawCommand("lrange", "mylist", 0, -1);
     * */
    protected function rawCommand(...$args){
        return $this->redisHandle->rawCommand($args);
    }
    //Transactions事务模式
    /*
     * 输入和退出事务模式。
     * 参数: 可选）redis：：multi或redis：：pipeline。
     * 默认为redis：：multi。一个redis：：多个命令块作为一个事务运行；
     * 一个redis：：pipeline块只是更快地传输到服务器，但不保证原子性。放弃取消事务。
     * return multi（）返回redis实例，进入多模式。一旦进入多模式，所有后续的方法调用都返回相同的对象，
     * 直到调用exec（）为止。
     * $ret = $redis->multi()->set('key1', 'val1')->get('key1')
    ->set('key2', 'val2')->get('key2')->exec();
     * */
    protected function multi(){
        return $this->redisHandle;
    }
    /*
     * 监视另一个客户端对key的修改。
     * 如果在watch和exec之间修改key，则multi/exec事务将失败（返回false）。unwatch取消此客户端对所有密钥的所有监视。
     * 参数: 一个键的字符串或键列表的数组
     *
     * */
    protected function watch($keyArr,$bool_unwatch = false){
        if ($bool_unwatch){
            return $this->redisHandle->unwatch($keyArr);
        }
        return $this->redisHandle->watch($keyArr);
    }
    //Scripting脚本
    /*
     * 执行解析lua脚本服务器端
     * 参数:script string.args array, 可选的.num_keys int, 可选的.
     * 返回的内容取决于lua脚本本身返回的内容，可以是标量值（int/string）或数组。
     * 返回的数组也可以包含其他数组，如果这是在lua脚本中设置的话。
     * 如果执行lua脚本时出错，getLasterror（）函数可以告诉您从redis返回的消息（例如编译错误）。
     * forexample // Nested response:  [1,2,3,['a','b','c']];
        $redis->eval("return {1,2,3,redis.call('lrange','mylist',0,-1)}");
     * */
    protected function evalEx($scriptString,$argsArray = false,$num_keys = false){
        return $this->redisHandle->evalEx($scriptString,$argsArray ,$num_keys );
    }
    /*
     * 从脚本的sha1散列（而不是脚本本身）计算lua脚本服务器端。
     * 为了运行这个命令，redis必须已经加载了脚本，可以运行它，也可以通过脚本加载命令。
     * 参数: script_sha string. 要运行的脚本的SHA1编码哈希。
        args array, 可选. 要传递给lua脚本的参数.
        num_keys int, 可选. 当redis旋转脚本时，应该进入keys数组的参数数与argv数组的参数数
     * */
    protected function evalSha($scriptSha,$argsArray = false,$num_keys = false){
        return $this->redisHandle->evalSha($scriptSha,$argsArray ,$num_keys );
    }
    /*
     * 执行redis script命令在脚本子系统上执行各种操作。
     * SCRIPT LOAD 成功时将返回传递的脚本的sha1散列，失败时返回false.
        SCRIPT FLUSH 应始终返回真
        SCRIPT KILL 如果脚本能够被杀死，则返回true；如果不能，则返回false
        SCRIPT EXISTS 将为每个传递的脚本返回一个包含true或false的数组
     * */
    protected function script($keyword,$args = false){
        $keyword = strtoupper($keyword);
        if ($keyword == 'LOAD'){
            return $this->redisHandle->script($keyword,$args);
        }elseif ($keyword == 'EXISTS'){
            return $this->redisHandle->script($keyword,$args);
        }
        return $this->redisHandle->script($keyword);
    }
    /*
     * 发出带有各种参数的client命令。
     * redis client命令可以通过四种方式使用。
     * CLIENT LIST
        CLIENT GETNAME
        CLIENT SETNAME [name]
        CLIENT KILL [ip:port]
    $redis->client('setname', 'somename'); // Set the name of the current connection
    $redis->client('kill', <ip:port>); // Kill the process at ip:port
    注意：phpredis将尝试重新连接，这样您就可以实际地终止自己的连接，但可能不会注意到丢失了它！
     * */
    protected function client($keyword,$args){
        $keyword = strtoupper($keyword);
        if ($keyword == 'LIST' || $keyword == 'GETNAME'){
            return $this->redisHandle->client($keyword);
        }
        return $this->redisHandle->client($keyword,$args);
    }
    /*
     * 最后一条错误消息（如果有）
     * return 带有最后返回的基于脚本的错误消息的字符串，如果没有错误，则为空
     * */
    protected function getLastError(){
        return $this->redisHandle->getLastError();
    }
    //清除最后一条错误消息
    protected function clearLastError(){
        return $this->redisHandle->clearLastError();
    }
    //使用phpredis的前缀设置为值加前缀的实用方法。
    protected function _prefix($prefix,$value){
        $this->redisHandle->setOption(Redis::OPT_PREFIX, $prefix);
        return $this->redisHandle->_prefix($value);
    }
    /*
     * 手动序列化值的实用程序方法。
     * 此方法允许您手动使用配置的序列化程序序列化值。
     * 这对于进出eval命令的数据的序列化/非序列化非常有用，因为phpredis本身无法自动执行此操作。
     * 注意，如果未设置序列化程序，phpredis将数组值更改为“array”，对象更改为“object”。
     *
     * */
    protected function _serialize($value,$keyword = false){
        $keyword = strtoupper($keyword);
        if ($keyword == 'NONE'){
            return $this->setOption(Redis::OPT_SERIALIZER,Redis::SERIALIZER_NONE);
        }elseif ($keyword == 'PHP'){
            return $this->setOption(Redis::OPT_SERIALIZER,Redis::SERIALIZER_PHP);
        }
        return $this->redisHandle->_serialize($value);
    }
    /*
     * 一种实用程序方法，用于使用设置的任何序列化程序取消数据序列化。
     * 如果没有序列化程序集，则返回的值将保持不变。如果设置了序列化程序，并且传入的数据格式不正确，则将引发异常。
     * 如果phpredis正在序列化值，并且您在序列化的lua脚本中从redis返回一些内容，那么这将非常有用。
     * */
    protected function _unserialize($value){
        return $this->redisHandle->_unserialize($value);
    }
    //一种确定phpredis对象是否认为它已连接到服务器的方法
    protected function isConnected(){
        return $this->redisHandle->isConnected();
    }
    //检索我们连接到的主机或Unix套接字
    //连接到的主机或Unix套接字，如果未连接则为False
    //找到我们连接的端口
    protected function getHostPort(){
        return array('host'=>$this->redisHandle->getHost(),'port'=>$this->redisHandle->getPort());
    }
    //获取指向phpredis的数据库号
    protected function getSetDbNum($dbIndex = -1){
        if ($dbIndex > -1){
            return $this->selectDBNumber($dbIndex);
        }
        return $this->redisHandle->getDbNum();
    }
    //获取用于phpredis的（写）超时
    //在connect调用中指定的超时（双精度），如果未连接，则为false
    //获取指定为phpredis的读取超时，如果未连接，则为false
    //返回读取超时（可以使用setoption和redis：：opt_read_timeout设置）如果未连接，则返回false
    protected function getSetTimeout($timeout = -1){
        if (is_array($timeout)){
            $this->setOption(Redis::OPT_READ_TIMEOUT,$timeout['read']);
            return $this->setOption(Redis::OPT_WRITE_TIMEOUT,$timeout['write']);
        }
        return array('read'=>$this->redisHandle->getReadTimeout(),'write'=>$this->redisHandle->getTimeout());
    }
    //获取phpredis正在使用的持久id。
    //返回phpredis正在使用的持久id（仅当连接到pconnect时才会设置），如果不使用持久id，则返回null，如果不连接，则返回false
    protected function getPersistentID(){
        return $this->redisHandle->getPersistentID();
    }
    //获取用于验证phpredis连接的密码
    //返回用于验证phpredis会话的密码；如果未使用密码，则返回null；如果未连接密码，则返回false
    protected function getAuth(){
        return $this->redisHandle->getAuth();
    }
    protected function close(){
        $this->redisHandle->close();
    }
    public function __destruct(){
        $this->close();
        $this->redisHandle = 0;
        $this->hostInfo = array();
    }

}